/*
 * Dump database data and format in unencrypted mode.
 * Supported format: CSV (0) and SQL (1)
 *
 * License: LGPL v3
 */
package org.passwordstore.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.passwordstore.Resource;

/**
 *
 * @author thotheolh
 */
public class DbDump {

    public int CSV_MODE = 0;
    public int SQL_MODE = 1;
    private StringBuilder strb;
    private int dumpMode = -1; //Current mode of dump (CSV or SQL)
    private String CSV_DELIMITER_CHAR = ",";
    private BufferedWriter bw;
    private String targetFilePath = "";

    public DbDump(int mode) {
        setDumpMode(mode);
    }

    //Main dump method for calling.
    public boolean doDump(String filename) {
        strb = new StringBuilder();
        if (getDumpMode() == CSV_MODE) {
            setTargetFilePath(filename);
            strb = generateCSVDump();
        } else if (getDumpMode() == SQL_MODE) {
            setTargetFilePath(filename);
            strb = generateSQLDump();
        } else {
        }
        return writeDump();
    }

    private StringBuilder generateSQLDump() {
        //Generate database schema.
        strb = new StringBuilder();
        Password pass = null;
        strb.append("-- SQL Dump created on: " + new java.util.Date().toString() + "\n");
        strb.append("CREATE CACHED TABLE IF NOT EXISTS PUBLIC.PASSWORDSTORE(USERNAME VARCHAR(1000) NOT NULL,"
                + "PASSWORD VARCHAR(1000) NOT NULL,"
                + "REQUIRED_PLACE VARCHAR(1000) NOT NULL);\n"
                + "ALTER TABLE PUBLIC.PASSWORDSTORE ADD CONSTRAINT PUBLIC.PASSWORDSTORE_PK PRIMARY KEY(USERNAME, PASSWORD, REQUIRED_PLACE);\n");
        //Generate database data.
        ArrayList list = Resource.getInstance().getSql().viewAllPasswordsWPass();
        if (!list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) { //Populating data StringBuffer
                pass = (Password) list.get(i);
                strb.append("INSERT INTO PASSWORDSTORE VALUES ('" + pass.getUname() + "','" + pass.getUpass() + "','" + pass.getRplace() + "');\n");
            }
        }
        return strb;
    }

    private StringBuilder generateCSVDump() {
        //Generate database schema with create and update statements.
        strb = new StringBuilder();
        strb.append("\"Username\"" + getCSVDelimiterChar() + "\"Password\"" + getCSVDelimiterChar() + "\"Required Place\"\n");
        Password pass = null;
        //Generate database data.
        ArrayList list = Resource.getInstance().getSql().viewAllPasswordsWPass();
        if (!list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) { //Populating data StringBuffer
                pass = (Password) list.get(i);
                strb.append("\"" + pass.getUname() + "\"" + getCSVDelimiterChar() + "\"" + pass.getUpass() + "\"" + getCSVDelimiterChar() + "\"" + pass.getRplace()+"\"\n");
            }
        }
        return strb;
    }

    /**
     * Set CSV delimiter character.
     * @param delimitertraversing
     */
    public void setCSVDelimiterChar(String delimiter) {
        CSV_DELIMITER_CHAR = delimiter;
    }

    /**
     * Get CSV delimiter character.
     * @return
     */
    public String getCSVDelimiterChar() {
        return CSV_DELIMITER_CHAR;
    }

    //Write out dump to file.
    private boolean writeDump() {
        if (strb != null) {
            try {
                bw = new BufferedWriter(new FileWriter(getTargetFilePath()));
                strb.trimToSize();
                System.out.println("Dump: " + dumpMode + " STRB: " + strb);
                bw.write(strb.toString());
                bw.flush();
                bw.close();
                return new File(getTargetFilePath()).exists();
            } catch (IOException ex) {
                Logger.getLogger(DbDump.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return false;
    }

    /**
     * @return the dumpMode
     */
    public int getDumpMode() {
        return dumpMode;
    }

    /**
     * @param dumpMode the dumpMode to set
     */
    public void setDumpMode(int dumpMode) {
        this.dumpMode = dumpMode;
    }

    /**
     * @return the targetFilePath
     */
    public String getTargetFilePath() {
        return targetFilePath;
    }

    /**
     * @param targetFilePath the targetFilePath to set
     */
    public void setTargetFilePath(String targetFilePath) {
        this.targetFilePath = targetFilePath;
    }
}
